<!-- 设备在2d地图上的点位编辑和显示轨迹功能 -->
<template>
  <div>
    <h1>图片标注工具</h1>
    <input type="file" id="imageUploader" accept="image/*" />
    <canvas id="canvas" :width="width" :height="height"></canvas>
    <button id="addButton" @click="handleStartDraw">添加标注</button>
    <button id="saveButton" @click="handleSave">保存标注</button>
    <button id="trackButton" @click="handleShowTrack">显示轨迹</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      points: [],
      width: 800,
      height: 600
    };
  },
  mounted() {
    const imageUploader = document.getElementById("imageUploader");
    const canvas = (this.canvas = document.getElementById("canvas"));
    const ctx = (this.ctx = canvas.getContext("2d"));
    // 处理图片上传
    imageUploader.addEventListener("change", e => {
      const file = e.target.files[0];
      const reader = new FileReader();
      reader.onload = event => {
        const img = this.img = new Image();
        img.onload = () => {
          const scale = this.calcScale(img, canvas);
          const drawWidth = scale * Math.max(this.width, img.width);
          const drawHeight = scale * Math.max(this.height, img.height);
          ctx.drawImage(
            img,
            (this.width - drawWidth) / 2,
            (this.height - drawHeight) / 2,
            drawWidth,
            drawHeight
          );
        };
        img.src = event.target.result;
      };
      reader.readAsDataURL(file);
    });
  },
  methods: {
    handleStartDraw() {
      const { points } = this;
      const canvas = document.getElementById("canvas");
      const ctx = canvas.getContext("2d");
      // 处理点击事件来标注点位
      canvas.addEventListener("click", e => {
        const rect = canvas.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        // 保存点位
        points.push({ x, y });
        // 在画布上绘制点
        ctx.fillStyle = "red";
        ctx.beginPath();
        ctx.arc(x, y, 5, 0, Math.PI * 2);
        ctx.fill();
      });
    },
    handleSave() {
      const { points } = this;
      const dataURL = canvas.toDataURL();
      const data = {
        image: dataURL,
        points: points
      };
      // 这里你可以使用AJAX将data发送到后端保存
      console.log(data);
    },
    // 显示轨迹
    handleShowTrack() {
      const trackData = [
        { time: "2024-06-17T10:00:00", name: "A", x: 50, y: 60 },
        { time: "2024-06-17T10:05:00", name: "B", x: 100, y: 160 },
        { time: "2024-06-17T10:10:00", name: "C", x: 150, y: 260 },
        { time: "2024-06-17T10:15:00", name: "D", x: 350, y: 360 }
      ];
      this.startAnimation(trackData);
    },
    startAnimation(points) {
      const {ctx} = this;
      points.sort((a, b) => new Date(a.time) - new Date(b.time)); // 按时间排序
      // ctx.drawImage(this.img, 0, 0);
      ctx.strokeStyle = "red";
      ctx.lineWidth = 2;
      let progress = 0;
      const that = this;
      this.idx = 0;
      console.log('a',points[this.idx])
      function animate() {
        that.ctx.clearRect(0, 0, that.width, that.height)
        that.img && that.ctx.drawImage(that.img, 0, 0); // 每次绘制前清除画布
        that.drawPartialTrajectory(progress,points);
        let animationFrameId;
        if (progress < points.length - 1) {
          progress += 0.01;
          animationFrameId = requestAnimationFrame(animate);
        } else {
          cancelAnimationFrame(animationFrameId);
        }
      }
      animate();
    },
    drawPartialTrajectory(progress,points) {
      const { ctx } = this;
      let lastIndex = Math.floor(progress);
      let remaining = progress - lastIndex;
      ctx.beginPath();
      ctx.moveTo(points[0].x, points[0].y);
      for (let i = 1; i <= lastIndex; i++) {
        ctx.lineTo(points[i].x, points[i].y);
      }
      if (lastIndex < points.length - 1) {
        let nextPoint = points[lastIndex + 1];
        let currentPoint = points[lastIndex];
        let interpolatedX =
          currentPoint.x + (nextPoint.x - currentPoint.x) * remaining;
        let interpolatedY =
          currentPoint.y + (nextPoint.y - currentPoint.y) * remaining;
        ctx.lineTo(interpolatedX, interpolatedY);
      }
      ctx.stroke();
      // 在每个已完成的点上绘制一个小圆
      for (let i = 0; i <= lastIndex; i++) {
        if(i > this.idx) {
          console.log('a',points[i])
          this.idx = i;
        }
        ctx.beginPath();
        ctx.arc(points[i].x, points[i].y, 5, 0, Math.PI * 2);
        ctx.fillStyle = "blue";
        ctx.fill();
      }
      // 标记点位名称
      ctx.fillStyle = "black";
      ctx.font = "12px Arial";
      for (let i = 0; i <= lastIndex; i++) {
        ctx.fillText(points[i].name, points[i].x + 10, points[i].y - 10);
      }
    },
    calcScale(img, canvas) {
      const w = img.width / canvas.getBoundingClientRect().width;
      const h = img.height / canvas.getBoundingClientRect().height;
      const scale = w > h ? w : h;
      return scale > 1 ? 1 / scale : scale;
    }
  }
};
</script>

<style>
#canvas {
  border: 1px solid black;
}
</style>
